package cn.enilu.flash.api.controller.business;

import cn.enilu.flash.api.controller.BaseController;
import cn.enilu.flash.api.service.AliPayment;
import cn.enilu.flash.api.service.SendMessage;
import cn.enilu.flash.api.service.WechatPay;
import cn.enilu.flash.api.utils.Nonce;
import cn.enilu.flash.utils.Maps;
import cn.enilu.flash.dao.MongoRepository;
import cn.enilu.flash.bean.entity.front.*;
import cn.enilu.flash.bean.entity.front.sub.OrderStatusBar;
import cn.enilu.flash.bean.vo.front.Rets;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.Calendar;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.wechat.pay.java.core.util.PemUtil;

@RestController
public class PaymentController extends BaseController {

        @Autowired
        private MongoRepository mongoRepository;

        Logger logger = LoggerFactory.getLogger(PaymentController.class);

        @PostMapping(value = "/v1/alipay/{orderId}/{cartId}")
        public String alipay(@PathVariable(value = "orderId") Long orderId, @PathVariable("cartId") Long cartId) {
                Order order = mongoRepository.findOne(Order.class, orderId);
                Carts cart = mongoRepository.findOne(Carts.class, cartId);
                AliPayment aliPayment = new AliPayment();
                Double totalFee = (double) (Double.valueOf(cart.getCart().getTotal()) - 4);
                String fromStr = aliPayment.createPayForm(order.getRestaurant_name(), order.getId().toString(),
                                totalFee.toString(), "http://8.142.93.96/alipay/callback", "http://baidu.com");
                return fromStr;
        }

        @RequestMapping(value = "/alipay/callback", method = RequestMethod.POST)
        public String alipaycallback(@RequestParam(value = "passback_params") String orderId) {
                Logger logger = LoggerFactory.getLogger(PaymentController.class);
                Order order = mongoRepository.findOne(Order.class, Long.valueOf(orderId));
                Shop shop = mongoRepository.findOne(Shop.class, Maps.newHashMap("name", order.getRestaurant_name()));
                Address address = mongoRepository.findOne(Address.class, order.getAddress_id());

                if (order.getStatus_code() == 0) {
                        // 发短信
                        String userphone = address.getPhone();
                        String shopphone = shop.getPhone();
                        String username = address.getName();
                        String building = address.getAddress_detail() + ",电话" + userphone + ",姓名" + username;
                        String message = "{\"item\":\"" + orderId + "\"," + "\"address\":\"" + building + "\"}";
                        SendMessage sendMessage = new SendMessage();

                        sendMessage.send(shopphone, "SMS_259810434", message);
                        // 修改订单状态
                        OrderStatusBar statusBar = order.getStatus_bar();
                        statusBar.setTitle(Order.getStatusCodeStr(1));
                        statusBar.setSub_title("已支付");
                        order.setStatus_bar(statusBar);
                        order.setStatus_code(1);
                        mongoRepository.update(order);
                }

                return "success";
        }

        @PostMapping(value = "/v1/wechatpay/{orderId}/{cartId}/{code}")
        public Object wechatpay(@PathVariable(value = "orderId") Long orderId, @PathVariable("cartId") Long cartId,
                        @PathVariable("code") String code) {

                String openidUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxac8b1ac7dfe9b329&secret=0eda7a266e41401b4339569e0c25a95d&code="
                                + code + "&grant_type=authorization_code";
                String prepayId = "";
                HttpURLConnection con = null;
                BufferedReader buffer = null;
                StringBuffer resultBuffer = null;
                try {
                        URL url = new URL(openidUrl);
                        // 得到连接对象
                        con = (HttpURLConnection) url.openConnection();
                        // 设置请求类型
                        con.setRequestMethod("GET");
                        // 设置Content-Type，此处根据实际情况确定
                        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                        // 允许写出
                        con.setDoOutput(true);
                        // 允许读入
                        con.setDoInput(true);
                        // 不使用缓存
                        con.setUseCaches(false);
                        int responseCode = con.getResponseCode();
                        if (responseCode == HttpURLConnection.HTTP_OK) {
                                // 得到响应流
                                InputStream inputStream = con.getInputStream();
                                // 将响应流转换成字符串
                                resultBuffer = new StringBuffer();
                                String line;
                                buffer = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
                                while ((line = buffer.readLine()) != null) {
                                        resultBuffer.append(line);
                                }
                                String openid = JSON.parseObject(resultBuffer.toString()).getString("openid");
                                logger.info("result:{}", resultBuffer.toString());
                                logger.info("openid:{}", openid);

                                Order order = mongoRepository.findOne(Order.class, orderId);
                                Carts cart = mongoRepository.findOne(Carts.class, cartId);
                                WechatPay wechatpay = new WechatPay();
                                Double totalFee = (double) (Double.valueOf(cart.getCart().getTotal()) - 4);
                                logger.info("totalFee:{}", totalFee);
                                prepayId = wechatpay.getPrepayId((int) (totalFee * 100),
                                                order.getRestaurant_name(),
                                                order.getId().toString() + "_orderid", openid,
                                                "http://diandian.api.leixiaolei.com/wechatpay/callback/"+orderId);

                                logger.info("prepayId:{}", prepayId);

                        }
                } catch (Exception e) {
                        e.printStackTrace();
                        logger.error("error {}", e.getMessage());
                        return null;
                }
                return createWechatOrderData(prepayId);
        }


        @PostMapping(value = "/wechatpay/callback/{orderId}")
        public String wechatcallback(@PathVariable(value = "orderId") Long orderId) {
                Logger logger = LoggerFactory.getLogger(OrderController.class);
                Order order = mongoRepository.findOne(Order.class, orderId);
                Shop shop = mongoRepository.findOne(Shop.class, Maps.newHashMap("name", order.getRestaurant_name()));
                Address address = mongoRepository.findOne(Address.class, order.getAddress_id());

                if (order.getStatus_code() == 0) {
                        // 发短信
                        String userphone = address.getPhone();
                        String shopphone = shop.getPhone();
                        String username = address.getName();
                        String building = address.getAddress_detail() + ",电话" + userphone + ",姓名" + username;
                        String message = "{\"item\":\"" + orderId + "\"," + "\"address\":\"" + building + "\"}";
                        SendMessage sendMessage = new SendMessage();

                        sendMessage.send(shopphone, "SMS_259810434", message);
                        // 修改订单状态
                        OrderStatusBar statusBar = order.getStatus_bar();
                        statusBar.setTitle(Order.getStatusCodeStr(1));
                        statusBar.setSub_title("已支付");
                        order.setStatus_bar(statusBar);
                        order.setStatus_code(1);
                        mongoRepository.update(order);
                }

                return "success";
        }

        
        @RequestMapping(value = "/wechat/code", method = RequestMethod.GET)
        public String wechatcode(@RequestParam("code") String code) {

                logger.info("code {}", code);
                return "success";
        }

        public Object createWechatOrderData(String prepay_id) {
                String appId = "wxac8b1ac7dfe9b329";
                String timestamp = String.valueOf(Calendar.getInstance().getTimeInMillis() / 1000);
                String nonceStr = Nonce.getRandomString(30);
                String signature = "";

                String message = appId + "\n" +  timestamp + "\n" + nonceStr + "\n"  + "prepay_id="+prepay_id +"\n";

                try {
                        logger.info("leo {}", "start key");
                        PrivateKey privateKey = toPrikey();
                        Signature sign = Signature.getInstance("SHA256withRSA");
                        logger.info("leo {}", "init start");
                        sign.initSign(privateKey);
                        logger.info("leo {}", "init end");
                        sign.update(message.getBytes("utf-8"));
                        logger.info("leo {}", "update end");
                        signature = Base64.getEncoder().encodeToString(sign.sign());
                        logger.info("signature {}", signature);
                } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }

                Map ret = Maps.newHashMap(
                                "appId", appId,
                                "timeStamp", timestamp,
                                "nonceStr", nonceStr,
                                "paySign", signature,
                                "package", prepay_id,
                                "signType", "RSA");
                logger.info("ret {}", ret);
                return Rets.success(ret);
        }

        public PrivateKey toPrikey() throws IOException {

                /** 商户API私钥路径 */
                String privateKeyPath = "/www/server/tomcat/diandiancuc/flash-waimai-master/flash-waimai-api/src/main/crt/wechatapiclient_key.pem";

                String prikey = readFile02(privateKeyPath);

                logger.info("prikey {}", prikey);

                
                PrivateKey privateKey =PemUtil.loadPrivateKeyFromPath(privateKeyPath);


                return privateKey;
        }

        public String readFile02(String path) throws IOException {
                StringBuilder file = new StringBuilder();
                // 使用一个字符串集合来存储文本中的路径 ，也可用String []数组
                FileInputStream fis = new FileInputStream(path);
                // 防止路径乱码 如果utf-8 乱码 改GBK
                InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                String line;
                while ((line = br.readLine()) != null) {
                        file.append(line);
                }
                br.close();
                isr.close();
                fis.close();
                return file.toString();
        }
}
